package cn.bonoon.kernel.web.controllers;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import cn.bonoon.kernel.events.PanelEvent;
import cn.bonoon.kernel.exceptions.PrivilegeException;
import cn.bonoon.kernel.exceptions.UnloginException;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.security.LogonUser;
import cn.bonoon.kernel.support.services.UserService;

/**
 * <pre>
 * V2.1--增加菜单跳转到其它子系统的功能
 * </pre>
 * <pre>
 * V3 进行了强力修改
 * 定义后台系统访问的标准访问路径，路径格式定义如下：
 * 标准：/[项目名]/[系统类别]/子系统/功能ID[/操作ID | /ID!操作ID]
 * 
 * 其中：
 * 1.项目名：如果在根目录下，则没有项目名
 * 2.系统类别：类别可分为前台或后台，系统类别是可以不定义的，如："/s/"开始表示后台系统；"/p/"开始表示门户界面等
 * 3.子系统：菜单里定义的子系统的访问名
 * 4.功能ID：菜单定义的功能的ID，所有属于该功能下的操作都应该以该路径开始
 * 5.操作ID：该功能下的操作
 * </pre>
 * @author jackson
 * @version 2.1
 */
public abstract class AbstractPanelController extends AbstractController{
	
	@Autowired
	protected ModuleManager moduleManager;
	
	@Autowired
	protected UserService userService;
	
	/** 该控制器的访问入口 */
	@RequestMapping(value = "!{key}/index.do", method = GET)//key=mid
	public final ModelAndView get(HttpServletRequest request, @PathVariable("key") String key) {
		return _get(request, key);
	}
	
	protected PanelParser buildParser(ModuleManager moduleManager, UserService userService){
		return new StandardLayoutParser(moduleManager, userService);
	}
	
	protected void initRequest(HttpServletRequest request){  }
	
	protected final ModelAndView _get(HttpServletRequest request, String mid) {
		try {
			
			LogonUser user = getUser();
			initRequest(request);
			
			/*
			 * 此处大大简化了以前版本的处理逻辑
			 * 这里简化为：
			 * 1.界面框架的解析器PanelParser
			 * 2.界面处理事件PanelEvent
			 */
			PanelParser parser = buildParser(moduleManager, userService);
			PanelEvent event = parser.parse(mid, request, user);
			event.getModel().addObject("authentication", user);
			try {
				// 可以由子类生成页面工作区的内容
				onLoad(event);
			} catch (Throwable t) {
				// 这里是子类抛出来的异常
				event.error(t);
			}
			return event.execute();
		} catch (PrivilegeException t) {
			//没有访问的权限
			return errorPanel(t);
		} catch (UnloginException t) {
			//进入当前功能需要用户登录，如果当前操作者还没有登录，则会直接跳转到登录界面
			return errorPanel(t);
		} catch (Throwable t) {
			//这里抛出操作异常
			return errorPanel(t);
		}
	}
	
	protected abstract void onLoad(PanelEvent event)throws Exception;
}
